<?php

	namespace Phptricks\system\library\custom_fields;

	/**
	 * To change this license header, choose License Headers in Project Properties.
	 * To change this template file, choose Tools | Templates
	 * and open the template in the editor.
	 * 
	 */
	use Phptricks\system\core\library\library as library;
	use Phptricks\system\library\PhptricksExceptions\PhptricksExceptions as Exc;

	class custom_fields implements library{

		private static $_instance = null;
		public $current_date = null;
		private $fields_type = null;
		private $fields_html = null;

		public static function getinstance(){
			if (self::$_instance === null) {
				self::$_instance = new \Phptricks\system\library\custom_fields\custom_fields();
			}
			return self::$_instance;
		}

		public function __construct(){
			$this->_initialize();
		}

		public function _initialize(){
			$this->fields_type = array(
				'text',
				'password',
				'hidden',
				'file',
				'textarea',
				'checkbox',
				'radio',
				'select',
			);

			$this->fields_html = array(
				'input' => '<input type="%s" name="%s" id="%s" value="%s" %s/>',
				'textarea' => '<textarea name="%s" id="%s" %s>%s</textarea>',
				'select' => '<select name="%s" id="%s" %s>%s</select>',
				'option' => '<option value="%s" %s>%s</option>' . "\n",
			);
		}

		public function my_json_encode($arr){
			if (isset($arr) && !empty($arr)) {
				array_walk_recursive($arr, function (&$item, $key) {
					if (is_string($item))
						$item = mb_encode_numericentity($item, array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
				});
				return mb_decode_numericentity(json_encode($arr, JSON_FORCE_OBJECT), array(0x80, 0xffff, 0, 0xffff), 'UTF-8');
			}
		}

		public function encode($array_data){
			$data_return = '';
			try {
				if (!empty($array_data)) {
					$array_data = $this->data_encode($array_data);
					$data_return = $this->my_json_encode($array_data);
					$this->current_date = $data_return;
					return $data_return;
				} else {
					return $array_data;
				}
			} catch (\Exception $e) {
				$this->current_date = $array_data;
				throw new Exc($e->getTraceAsString());
			}
		}

		public function decode($str_data){
			$data_return = '';
			try {
				if (!empty($str_data)) {
					$str_data = json_decode($str_data, true);
					$data_return = $this->data_decode($str_data);
					$this->current_date = $data_return;
					return $data_return;
				} else {
					return $str_data;
				}
			} catch (\Exception $e) {
				$this->current_date = $str_data;
				throw new Exc($e->getTraceAsString());
			}
		}

		public function data_encode($data_array){
			if (!empty($data_array) && count($data_array) > 0) {
				$array_return = array();
				foreach ($data_array as $key => $val) {
					if (is_array($val)) {
						$array_return[$key] = $this->data_encode($val);
					} else {
						if (!empty($val)) {
							$array_return[$key] = addcslashes(htmlspecialchars($val), '\\\<\>\?\+\_\)\(\*\&\^\%\$\#\@\!\~\"\'\=');
						} else {
							$array_return[$key] = '';
						}
					}
				}
				return $array_return;
			} else {
				return '';
			}
		}

		public function data_decode($data_array){
			if (!empty($data_array) && count($data_array) > 0) {
				$array_return = array();
				foreach ($data_array as $key => $val) {
					if (is_array($val)) {
						$array_return[$key] = $this->data_decode($val);
					} else {
						if (!empty($val)) {
							$array_return[$key] = stripcslashes(htmlspecialchars_decode($val));
						} else {
							$array_return[$key] = '';
						}
					}
				}
				return $array_return;
			} else {
				return '';
			}
		}

		public function update_key($key_name, $array_data, $new_adta){
//			pr($array_data,1);
			$select_data = '';

			foreach ($array_data as $key => $value) {
//				pr($value);
//				pr($new_adta);
//				echo $key_name;
				if (\in_array($key_name, array_keys($value))) {
					$select_data = $value[$key_name];
				}
			}
			pr($new_adta);
			pr($select_data);
			die();
		}

		public function _get_sub($parent_data = array(), $array_list = array()){
			$array_retrun = array();
			foreach ($array_list as $key => $value) {
				if ($value[$parent_data['sub_name']] == $parent_data['parent_id']) {
					$array_retrun[$value[$parent_data['parent_name']]] = $value;
				}
			}
			if (count($array_retrun) == 0) {
				$array_retrun = '';
			}
			unset($array_list);
			return $array_retrun;
		}

		/**
		 * 
		 * @param Array $array_fields
		 * 
		 * @example  <p>
		 * $array_fields_text = array(
		 * 		'count' => array(
		 * 			'field_type' => 'text',
		 * 			'field_default_value' => '25',
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm',
		 * 				'size' => '32',
		 * 			)
		 * 		)
		 * );
		 * $array_fields_password = array(
		 * 		count' => array(
		 * 			'field_type' => 'password',
		 * 			'field_default_value' => '25',
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm',
		 * 				'size' => '32',
		 * 			)
		 * 		)
		 * );
		 * $array_fields_hidden = array(
		 * 		'hidden_id' => array(
		 * 			'field_type' => 'hidden',
		 * 			'field_default_value' => '25'
		 * 		)
		 * );
		 * $array_fields_file = array(
		 * 		'file' => array(
		 * 			'field_type' => 'file',
		 * 			'field_default_value' => '25'
		 * 		)
		 * );
		 * $array_fields_files = array(
		 * 		'files[]' => array(
		 * 			'field_type' => 'file',
		 * 			'field_default_value' => array(
		 * 				'file_value1',
		 * 				'file_value2',
		 * 				'file_value3',
		 * 				'file_value4',
		 * 				'file_value5'
		 * 			)
		 * 		)
		 * );
		 * </p>
		 * 
		 */
		public function _get_fields($array_fields = array()){
			if (empty($array_fields) && !is_array($array_fields)) {
				throw new Exc('this $array_fields');
			}

			$array_return = array();

			foreach ($array_fields as $fields_keys => $fields_value) {
				if (!empty($fields_keys)) {
					if (isset($fields_value['field_type']) && !empty($fields_value['field_type'])) {
						if (in_array($fields_value['field_type'], $this->fields_type)) {
							$array_return[] = $this->_create_feilds($fields_keys, $fields_value);
						} else {
							throw new Exc('This type: "' . $fields_value['field_type'] . '" is unknown');
						}
					}
				}
			}
			return $array_return;
		}

		public function _create_feilds($feild_name, $array_data){
			$array_return = '';
			if (!empty($feild_name) && isset($feild_name)) {
				if (!empty($array_data) && isset($array_data) && is_array($array_data)) {
					if (isset($array_data['field_type']) && !empty($array_data['field_type'])) {
						if (in_array($array_data['field_type'], $this->fields_type)) {
							if (isset($array_data['field_attribut']) && is_array($array_data['field_attribut'])) {
								$array_data['field_attribut'] = $this->_get_attr($array_data['field_attribut']);
							} else {
								$array_data['field_attribut'] = '';
							}
							switch ($array_data['field_type']) {
								case 'text':
								case 'password':
								case 'hidden':
								case 'file':
								case 'radio':
								case 'checkbox':
									$array_return = $this->_create_input($feild_name, $array_data);
									break;
								case 'textarea':
									$array_return = $this->_create_textarea($feild_name, $array_data);
									break;
								case 'select':
									$array_return = $this->_create_select_box($feild_name, $array_data);
									break;
								default:
									throw new Exc('This type: "' . $array_data['field_type'] . '" is unknown');
							}
						} else {
							throw new Exc('This type: "' . $array_data['field_type'] . '" is unknown');
						}
					} else {
						throw new Exc('This variable : "' . $array_data['field_type'] . '" is empty');
					}
				} else {
					throw new Exc('Please check this variable : $array_data');
				}
			} else {
				throw new Exc('This variable : $feild_name is not set');
			}

			return $array_return;
		}

		private function _get_attr($field_attribut = array()){
			if (!isset($field_attribut) && !\is_array($field_attribut)) {
				throw new Exc('Please check this variable : $field_attribut');
			}
			$_field_attribut = '';
			$_array_field_attribut = array();
			foreach ($field_attribut as $key => $value) {
				$_array_field_attribut[] = $key . '="' . $value . '"';
			}
			if (count($_array_field_attribut) > 0) {
				$_field_attribut = implode(' ', $_array_field_attribut) . " ";
			} else {
				
			}
			return $_field_attribut;
		}

		/**
		 * 
		 * @param String $feild_name feild name like "username, city, age, id"
		 * @param Array $array_data like array('field_type', 'field_default_value', 'field_attribut')
		 * @return string html for input "text, password, hidden, file, radio, checkbox"
		 * <pre>
		 * see example:
		 * $array_fields_text = array(
		 * 		'textarea ' => array(
		 * 			'field_type' => 'textarea',
		 * 			'field_default_value' => 'This Is Test For Textarea',
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm',
		 * 				'size' => '32',
		 * 			)
		 * 		)
		 * 	);
		 * </pre>
		 */
		private function _create_input($feild_name, $array_data){
			$array_return = array();
			if (\is_array($array_data['field_default_value'])) {
				$count = 1;
				foreach ($array_data['field_default_value'] as $value) {
					$feild_id = \str_replace(array('[', ']'), '', $feild_name) . $count;
					$array_return[\str_replace(array('[', ']'), '', $feild_name)][] = sprintf($this->fields_html['input'], $array_data['field_type'], $feild_name, $feild_id, $value, $array_data['field_attribut']);
					$count++;
				}
			} else {
				$array_return[] = sprintf($this->fields_html['input'], $array_data['field_type'], $feild_name, $feild_name, $array_data['field_default_value'], $array_data['field_attribut']);
			}
			if (count($array_return) > 0) {
				return \implode("\n", $array_return);
			} else {
				return '';
			}
		}

		/**
		 * 
		 * @param String $feild_name feild name like "Description, Topic"
		 * @param Array $array_data like array('field_type', 'field_default_value', 'field_attribut')
		 * @return string html for textarea
		 * <pre>
		 * see example:
		 * $array_fields_text = array(
		 * 		'textarea ' => array(
		 * 			'field_type' => 'textarea',
		 * 			'field_default_value' => 'This Is Test For Textarea',
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm',
		 * 				'size' => '32',
		 * 			)
		 * 		)
		 * 	);
		 * </pre>
		 */
		private function _create_textarea($feild_name, $array_data){
			$array_return = sprintf($this->fields_html['textarea'], $feild_name, $feild_name, $array_data['field_attribut'], $array_data['field_default_value']);
			return $array_return;
		}

		/**
		 * @param String $feild_name feild name like "category, section"
		 * @param Array $array_data like array('field_type', 'field_default_value', 'field_attribut')
		 * @return string html for select box
		 * <pre>
		 * see example:
		 * $array_fields_select = array(
		 * 		'size' => array(
		 * 			'field_type' => 'select',
		 * 			'field_default_value' => 'medium',
		 * 			'field_disabled' => 'medium',
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm'
		 * 			),
		 * 			'field_other_values' => array(
		 * 				'small',
		 * 				'xsmall',
		 * 				'medium',
		 * 				'large',
		 * 				'xlarge',
		 * 				'xxlarge',
		 * 			)
		 * 		)
		 * );
		 * 
		 * OR Multiple
		 * 
		 * $array_fields_select_multiple = array(
		 * 		'size' => array(
		 * 			'field_type' => 'select',
		 * 			'field_default_value' => array(
		 * 				'xsmall',
		 * 				'medium',
		 * 				'xlarge'
		 * 			),
		 * 			'field_attribut' => array(
		 * 				'class' => 'form-control input-sm',
		 * 				'multiple' => 'multiple'
		 * 			),
		 * 			'field_other_values' => array(
		 * 				'small',
		 * 				'xsmall',
		 * 				'medium',
		 * 				'large',
		 * 				'xlarge',
		 * 				'xxlarge',
		 * 			)
		 * 		)
		 * );
		 * </pre>
		 */
		private function _create_select_box($feild_name, $array_data){
			$intersect = array_intersect((array) $array_data['field_default_value'], (array) $array_data['field_other_values']);
			$_array_option_value = array();
			if (\is_array($array_data['field_other_values']) && count($array_data['field_other_values']) > 0) {
				foreach ($array_data['field_other_values'] as $value) {
					$attar = '';
					if (\in_array($value, $intersect)) {
						$attar = $this->_get_attr(array(
							'selected' => 'selected'
						));
					}
					$_array_option_value[] = sprintf($this->fields_html['option'], $value, $attar, $value);
				}
				if (count($_array_option_value) > 0) {
					$_array_option_value = "\n" . \implode("", $_array_option_value);
				}
			} else {
				throw new Exc('Please check this key : field_other_values he must be array');
			}
			$array_return = sprintf($this->fields_html['select'], $feild_name, $feild_name, $array_data['field_attribut'], $_array_option_value);
			return $array_return;
		}

	}

//			$array_fields_select = array(
//				'size' => array(
//					'field_type' => 'select',
//					'field_default_value' => 'medium',
//					'field_disabled' => 'medium',
//					'field_attribut' => array(
//						'class' => 'form-control input-sm'
//					),
//					'field_other_values' => array(
//						'small',
//						'xsmall',
//						'medium',
//						'large',
//						'xlarge',
//						'xxlarge',
//					)
//				)
//			);
//			$array_fields_select_multi = array(
//				'size' => array(
//					'field_type' => 'select',
//					'field_default_value' => array(
//						'xsmall',
//						'medium',
//						'xlarge'
//					),
//					'field_attribut' => array(
//						'class' => 'form-control input-sm',
//						'multiple' => 'multiple'
//					),
//					'field_other_values' => array(
//						'small',
//						'xsmall',
//						'medium',
//						'large',
//						'xlarge',
//						'xxlarge',
//					)
//				)
//			);
//			$array_fields_files = array(
//				'files[]' => array(
//					'field_type' => 'file',
//					'field_default_value' => array(
//						'file_value1',
//						'file_value2',
//						'file_value3',
//						'file_value4',
//						'file_value5'
//					)
//				)
//			);
//			$_fields_data = $this->custom_fields->_get_fields($array_fields_files);
//			pr($_fields_data, 1);